package wuziqi;

import java.util.*;

// 基于评分的AI - 中级难度
class ScoreBasedAI implements AI {
    private Random random = new Random();
    
    @Override
    public int[] makeMove(GameState state, GameConfig config) {
        char[][] board = state.getBoard();
        int size = config.getBoardSize();
        char empty = config.getEmptySymbol();
        char aiPlayer = state.getCurrentPlayer();
        char humanPlayer = (aiPlayer == config.getPlayer1Symbol()) ? 
                          config.getPlayer2Symbol() : config.getPlayer1Symbol();
        
        // 获取所有空位置并评分
        List<ScoredMove> moves = new ArrayList<>();
        
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                if (board[i][j] == empty) {
                    int score = evaluateMove(board, i, j, aiPlayer, humanPlayer, config);
                    moves.add(new ScoredMove(i, j, score));
                }
            }
        }
        
        if (moves.isEmpty()) return null;
        
        // 按分数排序，选择最高分的移动
        moves.sort((a, b) -> b.score - a.score);
        
        // 如果有多个相同最高分，随机选择一个
        int maxScore = moves.get(0).score;
        List<ScoredMove> bestMoves = new ArrayList<>();
        for (ScoredMove move : moves) {
            if (move.score == maxScore) {
                bestMoves.add(move);
            }
        }
        
        ScoredMove bestMove = bestMoves.get(random.nextInt(bestMoves.size()));
        return new int[]{bestMove.row, bestMove.col};
    }
    
    private int evaluateMove(char[][] board, int row, int col, char aiPlayer, char humanPlayer, GameConfig config) {
        int score = 0;
        int winCount = config.getWinCount();
        
        // 检查8个方向
        int[][] directions = {{0,1}, {1,0}, {1,1}, {1,-1}};
        
        for (int[] dir : directions) {
            // 检查AI的潜在连线
            score += evaluateDirection(board, row, col, dir[0], dir[1], aiPlayer, humanPlayer, winCount) * 10;
            // 检查玩家的潜在连线（防守）
            score += evaluateDirection(board, row, col, dir[0], dir[1], humanPlayer, aiPlayer, winCount) * 8;
        }
        
        // 中心位置加分（对于开局）
        int center = config.getBoardSize() / 2;
        int distanceFromCenter = Math.abs(row - center) + Math.abs(col - center);
        score += (config.getBoardSize() - distanceFromCenter) * 2;
        
        return score;
    }
    
    private int evaluateDirection(char[][] board, int row, int col, int rowDir, int colDir, 
                                 char player, char opponent, int winCount) {
        int score = 0;
        
        // 正向检查
        int consecutive = 1; // 当前位置
        int openEnds = 0;
        
        // 检查正向
        int r = row + rowDir;
        int c = col + colDir;
        boolean foundOpponent = false;
        int count = 0;
        
        while (isValidPosition(board, r, c) && count < winCount - 1) {
            if (board[r][c] == player) {
                consecutive++;
            } else if (board[r][c] == opponent) {
                foundOpponent = true;
                break;
            } else {
                openEnds++;
                break;
            }
            r += rowDir;
            c += colDir;
            count++;
        }
        
        // 检查反向
        r = row - rowDir;
        c = col - colDir;
        count = 0;
        
        while (isValidPosition(board, r, c) && count < winCount - 1) {
            if (board[r][c] == player) {
                consecutive++;
            } else if (board[r][c] == opponent) {
                foundOpponent = true;
                break;
            } else {
                openEnds++;
                break;
            }
            r -= rowDir;
            c -= colDir;
            count++;
        }
        
        // 根据连续棋子和开放端评分
        if (consecutive >= winCount) {
            score += 10000; // 获胜
        } else if (consecutive == winCount - 1 && openEnds >= 1 && !foundOpponent) {
            score += 1000; // 差一步获胜
        } else if (consecutive == winCount - 2 && openEnds >= 1 && !foundOpponent) {
            score += 100; // 差两步获胜
        } else if (consecutive >= 2) {
            score += consecutive * 10; // 普通连线
        }
        
        return score;
    }
    
    private boolean isValidPosition(char[][] board, int row, int col) {
        return row >= 0 && row < board.length && col >= 0 && col < board[0].length;
    }
    
    private static class ScoredMove {
        int row, col, score;
        ScoredMove(int row, int col, int score) {
            this.row = row;
            this.col = col;
            this.score = score;
        }
    }
}